package com.deep.seata.standalone.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.deep.seata.standalone.mapper.OrdersMapper;
import com.deep.seata.standalone.mode.Orders;
import com.deep.seata.standalone.mode.Product;
import com.deep.seata.standalone.service.AccountService;
import com.deep.seata.standalone.service.OrderService;
import com.deep.seata.standalone.service.ProductService;


import com.deep.seata.standalone.task.MyTask;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.concurrent.*;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    private static Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private AccountService accountService;

    @Autowired
    private ProductService productService;

    @Override
    @DS(value = "order-ds")
    @GlobalTransactional //seata全局事务注解
    public Integer createOrder(Integer userId, Integer productId) throws Exception {
        Integer amount = 1; // 购买数量暂时设置为 1

        log.info("当前 XID: {}", RootContext.getXID());

        // 减库存 - 远程服务
        Product product = productService.reduceStock(productId, amount);

        // 减余额 - 远程服务
        accountService.reduceBalance(userId, product.getPrice());

        // 下订单 - 本地下订单
        Orders order = new Orders();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setPayAmount(product.getPrice().multiply(new BigDecimal(amount)));

//        ordersMapper.insertSelective(order);

        Integer orderId = addOrder(order);

        log.info("下订单: {}", orderId);
        int a = 1 / 0;
        // 返回订单编号

        return orderId;

    }

    /**
     * 不加事务，会增加订单
     *
     * @param userId
     * @param productId
     * @return
     * @throws Exception
     */
    @Override
    @DS(value = "order-ds")
    @GlobalTransactional //seata全局事务注解
    public Integer createOrder1(Integer userId, Integer productId) throws Exception {

        Integer amount = 1000; // 购买数量暂时设置为 1

        log.info("当前 XID: {}", RootContext.getXID());

        // 减库存 - 远程服务
        Product product = productService.reduceStock(productId, amount);

        // 减余额 - 远程服务
        accountService.reduceBalance(userId, product.getPrice());

        // 下订单 - 本地下订单
        Orders order = new Orders();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setPayAmount(product.getPrice().multiply(new BigDecimal(amount)));

        Integer orderId = addOrder(order);

        log.info("下订单: {}", orderId);
        return orderId;
    }

    @Override
    @DS(value = "order-ds")
    @GlobalTransactional //seata全局事务注解
    public Integer createOrder2(Integer userId, Integer productId) throws Exception {
        Integer amount = 1; // 购买数量暂时设置为 1

        log.info("当前 XID: {}", RootContext.getXID());

        // 减库存 - 远程服务
        Product product = productService.reduceStock(productId, amount);

        BigDecimal price = new BigDecimal(22222.2);

        // 减余额 - 远程服务
        accountService.reduceBalance(userId, price);

        // 下订单 - 本地下订单
        Orders order = new Orders();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setPayAmount(product.getPrice().multiply(new BigDecimal(amount)));

        Integer orderId = addOrder(order);

        log.info("下订单: {}", orderId);
        return orderId;
    }

    @Override
    @DS(value = "order-ds")
    @GlobalTransactional //seata全局事务注解
    public Integer createOrder3(Integer userId, Integer productId) throws Exception {

        Integer amount = 1; // 购买数量暂时设置为 1

        log.info("当前 XID: {}", RootContext.getXID());

        // 减库存 - 远程服务
        Product product = productService.reduceStock(productId, amount);

        // 减余额 - 远程服务
        accountService.reduceBalance(userId, product.getPrice());

        int a = 1 / 0;

        // 下订单 - 本地下订单
        Orders order = new Orders();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setPayAmount(product.getPrice().multiply(new BigDecimal(amount)));

        Integer orderId = addOrder(order);

        log.info("下订单: {}", orderId);
        return orderId;
    }

    @Override
    @GlobalTransactional //seata全局事务注解
    public Integer createOrder4(Integer userId, Integer productId) throws Exception {

        Integer amount = 1; // 购买数量暂时设置为 1

        log.info("当前 XID: {}", RootContext.getXID());

        // 减库存 - 远程服务
        Product product = productService.reduceStock(productId, amount);

        // 减余额 - 远程服务
        accountService.reduceBalance(userId, product.getPrice());

        Thread.sleep(10000);

        // 下订单 - 本地下订单
        Orders order = new Orders();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setPayAmount(product.getPrice().multiply(new BigDecimal(amount)));

        Integer orderId = addOrder(order);

        log.info("下订单: {}", orderId);
        return orderId;
    }

    @Override
    @GlobalTransactional //seata全局事务注解
    public Integer createOrder5(Integer userId, Integer productId) throws Exception {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(5));

        for (int i = 0; i < 15; i++) {
            MyTask myTask = new MyTask(i);
            executor.execute(myTask);
            System.out.println("线程池中线程数目：" + executor.getPoolSize() + "，队列中等待执行的任务数目：" +
                    executor.getQueue().size() + "，已执行玩别的任务数目：" + executor.getCompletedTaskCount());
        }
        executor.shutdown();

        return 1;
    }

    public Integer addOrder(Orders order) {
        ordersMapper.insertSelective(order);
        return order.getId();
    }
}